package com.csair.seam.domain.service.impl;

import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.csair.seam.domain.service.IEhomeService;
import com.csair.seam.infrastructure.ehome.EhomeConfigurationProperties;
import com.csair.seam.infrastructure.ehome.EhomeParam;
import com.csair.seam.infrastructure.ehome.EhomeParamData;
import com.csair.seam.infrastructure.ehome.EhomeResult;
import com.csair.seam.infrastructure.ehome.EpnsConfig;
import com.csair.seam.infrastructure.ehome.LoginConfig;
import com.csair.seam.infrastructure.ehome.NoticeBundle;
import com.csair.seam.infrastructure.ehome.NoticeMsgType;
import com.csair.seam.infrastructure.ehome.NoticeResult;
import com.csair.seam.infrastructure.ehome.NoticeRichText;
import com.csair.seam.infrastructure.exception.BizException;
import com.csair.seam.infrastructure.exception.ExceptionUtil;
import com.csair.seam.infrastructure.log.InterfaceCallLogInfo;
import com.csair.seam.infrastructure.utils.AESHelper;
import com.csair.seam.infrastructure.utils.DateHelper;
import com.csair.seam.infrastructure.utils.RSAUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @Author: wurunbin
 * @Date: 2020/3/5 15:10
 * @Description:
 **/
@Service
@Slf4j
public class EhomeServiceImpl implements IEhomeService {

    @Autowired
    private RestTemplate restTemplate;
    
    @Autowired
    private EhomeConfigurationProperties ehomeConfigurationProperties;

    private static final String RSA_ENCRYPT_PUBLICK_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCICjluGEKsq0BhamkhCRtyD5JTMt/3hJa0BlrVWuDwyQeeEw7p/AYe6347tDneewWjabMhuizuJqh3YWNz89v9IRB3IMr0uRGu5a5gUmA7xcUsmip7TMLnkjF4vbGHz53xi4Cgb9CUE4bXoYtyv0Ag4Z9cnV48wa/jciaTxH0ddwIDAQAB";

    @Override
    public EhomeResult checkLogin(String username, String deviceId, String ssoToken) {
    	LoginConfig loginConfig = ehomeConfigurationProperties.getLogin();
    	
        EhomeParamData paramData = new EhomeParamData(username,deviceId,ssoToken);
        EhomeParam param = new EhomeParam(loginConfig.getAppid(),loginConfig.getPassword(),paramData);
        
        InterfaceCallLogInfo callLogInfo = new InterfaceCallLogInfo();
        callLogInfo.setInterfaceDescription("E家登录验证接口");
        callLogInfo.setUrl(loginConfig.getUrl());
        callLogInfo.setMethod("POST");
        callLogInfo.setCallTime(DateHelper.getCurrentDateTimeStr());
        try{
            String data = AESHelper.aesEncrypt(param.toString(), loginConfig.getKey());
            String sign = RSAUtils.encryptByPublicKey(loginConfig.getKey(),RSA_ENCRYPT_PUBLICK_KEY);
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            HttpHeaders header = new HttpHeaders();
            header.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            map.add("loginAccount",username);
            map.add("data",data);
            map.add("sign",sign);
            HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, header);
            ResponseEntity<EhomeResult> response = restTemplate.postForEntity(loginConfig.getUrl(), entity, EhomeResult.class);
            
            boolean success = response.getBody().getResult().equals("0")?true:false;
            callLogInfo.setSuccess(success);
            log.info("【接口调用】：{}",JSON.toJSONString(callLogInfo));
            return response.getBody();
        }catch (Exception e){
        	callLogInfo.setSuccess(false);
        	callLogInfo.setStackInfo(ExceptionUtil.getStackTrace(e));
        	log.info("【接口调用】：{}",JSON.toJSONString(callLogInfo));
            throw new BizException("E家登录验证失败");
        }
    }

	@Override
	public NoticeResult pushText(String content,String toUser) {
		EpnsConfig epnsConfig = ehomeConfigurationProperties.getEpns();
		// e家消息推送对象
		NoticeBundle noticeBundle = new NoticeBundle();
		// 推送文本
        noticeBundle.setAppId(epnsConfig.getAppid())
                .setPwd(epnsConfig.getPassword())
                .setMsgType(NoticeMsgType.MSG_TYPE_TEXT)
                .setContent(content)
                .setToUsers(toUser);
        String rawData = JSON.toJSONString(noticeBundle);
        return pushEhome(rawData);
	}

	@Override
	public NoticeResult pushRichText(String title, String content, String url, String urlDesc, String toUser) {
		EpnsConfig epnsConfig = ehomeConfigurationProperties.getEpns();
		NoticeRichText richText = new NoticeRichText(title, content, url, urlDesc);
		NoticeBundle noticeBundle = new NoticeBundle();
        noticeBundle.setAppId(epnsConfig.getAppid())
                .setPwd(epnsConfig.getPassword())
                .setMsgType(NoticeMsgType.MSG_TYPE_RICHTEXT)
                .setRichText(richText)
                .setToUsers(toUser);
        String rawData = JSON.toJSONString(noticeBundle);
        return pushEhome(rawData);
	}
	
	private NoticeResult pushEhome(String rawData) {
		log.info("rawData = {}", rawData);
		try {
			EpnsConfig epnsConfig = ehomeConfigurationProperties.getEpns();
			// data, sign加密
			String aesKey = UUID.randomUUID().toString().replace("-","");
			String sign = RSAUtils.encryptByPublicKey(aesKey, RSA_ENCRYPT_PUBLICK_KEY);
			String data = AESHelper.aesEncrypt(rawData, aesKey);
			log.info("data = {}", data);
			log.info("sign = {}", sign);
			
			// 推送并查看结果
			MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();
			HttpHeaders header = new HttpHeaders();
			header.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
			paramMap.add("data",data);
			paramMap.add("sign",sign);
			HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(paramMap, header);
			ResponseEntity<String> response = restTemplate.postForEntity(epnsConfig.getUrl(), entity, String.class);
			log.info("response = {}", response.getBody());
			NoticeResult noticeResult = JSON.parseObject(response.getBody(), NoticeResult.class);
			return noticeResult;
		} catch (Exception e) {
			log.error(e.getMessage(),e);
			return null;
		}
	}
    
}
